/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package aprendizajePorRefuerzo.entorno;

import aprendizajePorRefuerzo.accion.Accion;
import aprendizajePorRefuerzo.accion.AccionGrilla;
import aprendizajePorRefuerzo.estado.Estado;
import aprendizajePorRefuerzo.estado.EstadoGrilla;
import aprendizajePorRefuerzo.reward.RewardImp;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Fernando Sorzana
 */
public class EntornoConViento extends EntornoGrilla {
    
    private List<Integer> viento;
    
    public EntornoConViento(int cantidadFilas,int cantidadColumnas){
        super(cantidadFilas,cantidadColumnas);
        viento = new ArrayList<>();
        for (int i = 0; i < cantidadColumnas; i++){
            viento.add(0);
        }
    }

    public List<Integer> getViento() {
        return viento;
    }

    public void setViento(List<Integer> viento) {
        this.viento = viento;
    }

    @Override
    public void setCantidadColumnas(int cantidadColumnas) {
        super.setCantidadColumnas(cantidadColumnas);
        viento.clear();
        for (int i = 0; i < cantidadColumnas; i++){
            viento.add(0);
        }
    }
    
    
    
     @Override
    public RespuestaEntorno devolverRespuesta(Estado estado, Accion accion) {
        if (!EstadoGrilla.class.isAssignableFrom(estado.getClass()) || !AccionGrilla.class.isAssignableFrom(accion.getClass())){
            return null;
        } else {
            int columnaNueva = ((EstadoGrilla) estado).getColumna() + ((AccionGrilla) accion).getCambioColumna();
            if (columnaNueva < 0 || columnaNueva >= getCantidadColumnas()){
                columnaNueva = ((EstadoGrilla) estado).getColumna();
            }
            int filaEstado = ((EstadoGrilla) estado).getFila();
            int posibleFilaNueva = filaEstado + ((AccionGrilla) accion).getCambioFila() + viento.get(filaEstado);
            int filaNueva = filaEstado;
            if (posibleFilaNueva >= filaEstado){
                for (int i = filaEstado; i <= posibleFilaNueva; i++){
                    EstadoGrilla estadoNuevo = new EstadoGrilla(false, true, i, columnaNueva);
                    if (i >= 0 && i < getCantidadFilas() && !getIntransitables().contains(estadoNuevo)){
                        filaNueva = i;
                    } else {
                        break;
                    }
                }
            } else {
                for (int i = filaEstado; i >= posibleFilaNueva; i--){
                    EstadoGrilla estadoNuevo = new EstadoGrilla(false, true, i, columnaNueva);
                    if (i >= 0 && i < getCantidadFilas() && !getIntransitables().contains(estadoNuevo)){
                        filaNueva = i;
                    } else {
                        break;
                    }
                }
            }
            EstadoGrilla estadoNuevo = new EstadoGrilla(false, true, filaNueva, columnaNueva);
            if (getIntransitables().contains(estadoNuevo)){
                return new RespuestaEntorno(getRewardComun(),estado);
            }
            if (getFinales().contains(estadoNuevo)){
                estadoNuevo.setFinal(true);
            }
            RewardImp reward = estadoNuevo.esFinal() ? getRewardFinal() : getRewardComun();
            return new RespuestaEntorno(reward, estadoNuevo);
        }
    }
    
}
